package com.security.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chai
 * @since 2020/11/3
 */
public class LoginFilter extends UsernamePasswordAuthenticationFilter {

    @Autowired
    private SessionRegistry sessionRegistry;

    public LoginFilter(AuthenticationManager authenticationManager) {
        this.setAuthenticationManager(authenticationManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (!"POST".equals(request.getMethod())) {
            throw new AuthenticationServiceException("Authentication method not supported :" + request.getMethod());
        }
        if (!StringUtils.equals(request.getContentType(), MediaType.APPLICATION_JSON_UTF8_VALUE)) {
            // 处理key/value参数格式
            return super.attemptAuthentication(request, response);
        }
        // 处理json参数格式
        Map<String, Object> loginData = new HashMap<>();
        try {
            loginData = new ObjectMapper().readValue(request.getInputStream(), Map.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String username = StringUtils.defaultString(loginData.get(getUsernameParameter()).toString()).trim();
        String password = StringUtils.defaultString(loginData.get(getPasswordParameter()).toString());
        // 把RememberMe字段添加到请求体中
//        PersistentTokenBasedRememberMeServices rememberMeServices = (PersistentTokenBasedRememberMeServices) getRememberMeServices();
//        request.setAttribute(rememberMeServices.getParameter(), loginData.get(rememberMeServices.getParameter()).toString());
        // 验证用户
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
        setDetails(request, token);
        // 在session中添加一条记录 使用Spring-Session可不用此操作
//        sessionRegistry.registerNewSession(request.getSession(true).getId(),
//                // 这里需要添加一个重写了equals和hasCode方法的对象来保证唯一
//                new User(token.getPrincipal().toString(), token.getCredentials().toString(), token.getAuthorities()));
        return this.getAuthenticationManager().authenticate(token);
    }

}
